/**
 * @author Created by qiush on 2017-06-28.
 */

import * as React from 'react';
import {ComponentDecorator, connect} from 'react-redux';

import {AppState} from '../store/index';
import util from '../common/util';

export interface StickyOwnProps {
  designId: string;
}

export interface StickyMergedProps {
  scrollTop?: number;
}

type StickyProps = StickyOwnProps & StickyMergedProps;

export interface StickyState {
  status: 'NORMAL' | 'STICKY';
  containerStyle: React.CSSProperties;
  holderStyle: React.CSSProperties;
  wrapperStyle: React.CSSProperties;
}

function mapStateToProps(state: AppState, ownProps: StickyOwnProps): StickyMergedProps {
  const designId = ownProps.designId;

  const scrollTop = state.scrollTopState[designId];
  return {
    scrollTop
  };
}

class Sticky extends React.Component<StickyProps, StickyState> {
  private ref: Element;
  private stickyPos: ClientRect;

  constructor(props: StickyProps) {
    super(props);

    this.state = {
      status: 'NORMAL',
      containerStyle: {},
      holderStyle: {},
      wrapperStyle: {}
    };
  }

  render() {
    return (
      <div ref={this.updateRef}>
        <div style={this.state.holderStyle}/>
        <div style={this.state.containerStyle}>
          <div style={this.state.wrapperStyle}>
            {this.props.children}
          </div>
        </div>
      </div>
    );
  }

  componentWillReceiveProps(nextProps: StickyProps) {
    if (nextProps.scrollTop === this.props.scrollTop || !this.ref) {
      return;
    }

    console.info(nextProps);
    if (nextProps.scrollTop > this.stickyPos.top) {
      this._tryStick();
    } else {
      this._tryUnStick();
    }
  }

  private updateRef = el => {
    this.ref = el;
    this.stickyPos = this.ref.getBoundingClientRect();
  }

  private _tryStick() {
    if (this.state.status === 'STICKY') {
      // 已经是停在顶部了, 不用再处理了
      return;
    }

    this.setState({
      ...this.state,
      status: 'STICKY',
      containerStyle: {
        position: 'fixed',
        top: 0,
        left: 150,
        right: 350,
        zIndex: 10000,
        background: this._getChildrenBackground()
      },
      holderStyle: {
        height: this.stickyPos.height
      },
      wrapperStyle: {
        width: this.stickyPos.width,
        margin: '0 auto'
      }
    });
  }

  private _tryUnStick() {
    if (this.state.status === 'NORMAL') {
      // 如果已经是在原来位置了, 那么不用处理了
      return;
    }


    this.setState({
      ...this.state,
      status: 'NORMAL',
      containerStyle: {},
      holderStyle: {
        height: 0
      },
      wrapperStyle: {}
    });
  }

  private _getChildrenBackground(): string | null {
    if (!util.isReactElement(this.props.children)) {
      return null;
    }
    if (!this.props.children.props.style) {
      return null;
    }
    if (this.props.children.props.style.background) {
      return this.props.children.props.style.background;
    }
    return this.props.children.props.style.backgroundColor;
  }
}

type StickyDecorator = ComponentDecorator<StickyMergedProps, StickyOwnProps>;
const componentDecorator: StickyDecorator = connect(mapStateToProps);
export default componentDecorator(Sticky);
